package com.think.common.utils;

import java.lang.reflect.Array;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 系统工具类
 * </p>
 *
 * @author: xwj
 * @data: 2019-04-06
 */
public class SysUtils {
    /**
     * 判断object是否为空,集合会校验size
     *
     * @param objs
     * @return boolean
     * @author xwj
     * @date 2019/1/30 16:44
     */
    public static boolean isNull(Object... objs) {
        for (Object obj : objs) {
            if (isEmpty(obj)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断object是否不为空,集合会校验size
     *
     * @param obj
     * @return boolean
     * @author xwj
     * @date 2019/1/30 16:44
     */
    public static boolean isNotNull(Object... obj) {
        return !isNull(obj);
    }

    /**
     * 对象非空判断
     *
     * @param obj
     * @return boolean
     * @author xwj
     * @date 2019/1/30 16:45
     */
    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    /**
     * 对象空判断
     *
     * @param obj
     * @return boolean
     * @author xwj
     * @date 2019/1/30 16:45
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null || obj.toString().equals("")) {
            return true;
        }

        if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }
        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }
        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }

        return false;
    }

    /**
     * <p>
     * MD5算法加密 不可逆算法
     * </p>
     * @author CaiWenYi
     * @Date: 2020/7/7 21:08
    */
    public static String md5(String strSrc) {
        String outString = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] outByte = md5.digest(strSrc.getBytes("UTF-8"));
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < outByte.length; offset++) {
                i = outByte[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            outString = buf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return outString;
    }

    /**
     * 返回指定格式的字符型日期
     *
     * @param date
     * @param formatString
     * @return
     */
    public static String date2String(LocalDateTime date, String formatString) {
        if (isEmpty(date)) {
            return null;
        }
        SimpleDateFormat simpledateformat = new SimpleDateFormat(formatString);
        String strDate = simpledateformat.format(date);
        return strDate;
    }

    /**
     * <p>
     * 将字符串型日期转换为日期型
     * </p>
     *
     * @author CaiWenYi
     * @date 2020-07-09 05:18:14
     */
    public static LocalDateTime stringToLocalDateTime(String strDate) {
        DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(strDate, timeDtf);
        return localDateTime;
    }

    /**
     * <p>
     * 将LocalDateTime转换Date
     * </p>
     *
     * @author CaiWenYi
     * @date 2020-07-09 05:18:09
     */
    public static Date LocalDateTimeToDate(LocalDateTime strDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = strDate.atZone(zone).toInstant();
        Date date = Date.from(instant);
        return date;
    }

    /**
     * <p>
     * 格式化时间
     * </p>
     * @author CaiWenYi
     * @Date: 2020/3/15 21:37
    */
    public static String formatTime(LocalDateTime date, String formatString) {
        if (isEmpty(date)) {
            return null;
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatString);
        String returnTime = dateTimeFormatter.format(date);
        return returnTime;
    }


    /**
     * <p>
     * 获取当天指定时分秒
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
    */
    public static LocalDateTime getTimesmorning(Integer hourOfDay, Integer minute, Integer second) {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), hourOfDay, minute, second);
        Date beginOfDate = cal.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(formatter.format(beginOfDate),df);
    }

    /**
     * <p>
     * 获取下个月当天日期
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
     */
    public static LocalDate getNextMonthDay() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
        cal.add(Calendar.MONTH, 1);//取后一个月的同一天
        Date beginOfDate = cal.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(formatter.format(beginOfDate),df);
    }

    /**
     * <p>
     * 获取3天后的年月日
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
     */
    public static String getThreeDay() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
        cal.add(Calendar.DATE, 3);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        String three_days_after = sdf2.format(cal.getTime());
        return three_days_after;
    }

    /**
     * <p>
     * 获取上个月的年月
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
     */
    public static String getLastYearMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
        Calendar calendar = Calendar.getInstance();
        //获取下个月的年份月份
        calendar.add(Calendar.MONTH, -1);
        String nextMonth = sdf.format(calendar.getTime());
        return nextMonth;
    }

    /**
     * <p>
     * 获取下个月的年月
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
     */
    public static String getNextYearMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
        Calendar calendar = Calendar.getInstance();
        //获取下个月的年份月份
        calendar.add(Calendar.MONTH, 1);
        String nextMonth = sdf.format(calendar.getTime());
        return nextMonth;
    }

    /**
     * <p>
     * 根据LocalDate获取下个月当天日期
     * </p>
     * @author CaiWenYi
     * @Date: 2019/8/12 0:22
     */
    public static LocalDate getLocalDateNextMonthDay(LocalDate dateTime) {
        Calendar cal = Calendar.getInstance();
        cal.set(dateTime.getYear(),dateTime.getMonthValue()-1, dateTime.getDayOfMonth());
        cal.add(Calendar.MONTH, 1);//取后一个月的同一天
        Date beginOfDate = cal.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(formatter.format(beginOfDate),df);
    }

    /**
     * <p>
     * 获取下个月20号日期
     * </p>
     * @author CaiWenYi
     * @Date: 2020/3/13 0:25
    */
    public static LocalDate getNextMonthTwentyDay() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 1);//取后一个月的同一天
        cal.set(Calendar.DAY_OF_MONTH, 20);
        Date beginOfDate = cal.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(formatter.format(beginOfDate),df);
    }

    /**
     * <p>
     * 获取多少天后的日期
     * </p>
     *
     * @author CaiWenYi
     * @date 2020-12-08 05:05:05
     */
    public static LocalDate getHowDay(int day) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, day);
        Date beginOfDate = cal.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(formatter.format(beginOfDate),df);
    }

    public static void main(String[] args) {
        System.err.println(getNextMonthTwentyDay());
        System.err.println(getThreeDay());
        System.err.println(getTimesmorning(00,00,00));
        System.err.println(getNextYearMonth());

        System.err.println(getLocalDateNextMonthDay(LocalDate.of(2011,01,31)));
        System.err.println(getHowDay(29));
    }

}
